package com.maimao.kill.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.maimao.core.utils.DateUtils;
import com.maimao.kill.entity.vo.KillGoodsShowVo;
import com.maimao.model.kill.KillGoods;
import com.maimao.model.kill.Schedule;
import com.maimao.model.kill.vo.KillGoodsVo;
import org.checkerframework.checker.units.qual.K;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 单品秒杀商品详情页数据缓存
 *
 * @author MaoLin Wang
 * @date 2021/4/22 下午9:27
 */
@Service
public class KillCacheService {

    public static final int DEFAULT_SCHEDULE_SHOW_SIZE = 5;
    private final List<Schedule> scheduleListCache = Lists.newCopyOnWriteArrayList();

    private final Map<Long, List<KillGoodsVo>> killGoodsMap = Maps.newHashMap();

    public void add(List<Schedule> scheduleList) {
        if (ObjectUtil.isNotEmpty(scheduleList)) {
            scheduleListCache.removeAll(scheduleList);
            scheduleListCache.addAll(scheduleList.
                    stream()
                    .sorted(Comparator.comparing(Schedule::getStartTime))
                    .collect(Collectors.toList()));
        }

    }

    /**
     *
     * @desc 按goodsId分组保存到KillGoods的skus中
     * @param scheduleId    排期id
     * @param killGoodsList 该排期下的商品
     */
    public void putGoods(Long scheduleId, List<KillGoods> killGoodsList) {
        if (ObjectUtil.isNotEmpty(killGoodsList)) {
            Map<Long, List<KillGoods>> goodsGroup = killGoodsList.stream().collect(Collectors.groupingBy(KillGoods::getGoodsId));
            List<KillGoodsVo>killGoodsVoList=Lists.newArrayListWithCapacity(goodsGroup.size());
            KillGoodsVo vo;
            for (Map.Entry<Long, List<KillGoods>> entry : goodsGroup.entrySet()) {
                vo=new KillGoodsVo();
                vo.setGoodsId(entry.getKey());
                vo.setSkus(entry.getValue());
                killGoodsVoList.add(vo);
            }
            killGoodsMap.put(scheduleId,killGoodsVoList);
        }

    }

    public KillGoodsShowVo currentShowKillGoodsData() {
        KillGoodsShowVo vo = new KillGoodsShowVo();
        if (ObjectUtil.isNotEmpty(scheduleListCache)) {
            LocalDateTime now = DateUtils.now();
            Schedule killingSchedule = scheduleListCache.stream().filter(schedule -> between(schedule.getStartTime(), now, schedule.getEndTime()))
                    .findFirst().orElse(null);
            if (killingSchedule != null) {
                List<KillGoodsVo> onKillGoodsList = killGoodsMap.get(killingSchedule.getId());
                String onKillStarTime = killingSchedule.getStartTime().format(DateTimeFormatter.ofPattern("hh:mm"));
                vo.setOnKillGoodsData(new HashMap<String, List<KillGoodsVo>>() {{
                    put(onKillStarTime, onKillGoodsList);
                }});
            }

            //后面4个排期
            List<Schedule> scheduleList = Lists.newArrayListWithCapacity(DEFAULT_SCHEDULE_SHOW_SIZE - 1);
            int count = 0;
            for (Schedule schedule : scheduleListCache) {
                if (count >= (DEFAULT_SCHEDULE_SHOW_SIZE - 1)) {
                    break;
                }
                if (schedule.getStartTime().compareTo(now) > 0) {
                    scheduleList.add(schedule);
                    count++;
                }
            }
            Map<String, List<KillGoodsVo>> scheduleGoodsData = Maps.newLinkedHashMapWithExpectedSize(scheduleList.size());
            for (Schedule schedule : scheduleList) {
                scheduleGoodsData.put(getTimeStr(schedule.getStartTime()), killGoodsMap.get(schedule.getId()));
            }
            vo.setScheduleGoodsData(scheduleGoodsData);
        }
        return vo;
    }

    private String getTimeStr(LocalDateTime startTime) {
        return startTime.format(DateTimeFormatter.ofPattern("MM月dd日 HH:mm"));
    }


    private boolean between(LocalDateTime fromTime, LocalDateTime target, LocalDateTime toTime) {
        return (target.compareTo(fromTime) >= 0) && (target.compareTo(toTime) < 0);
    }
}
